package com.gzhryc.shared_device.oem.micro.api.controllers.xcx.v1.bxscn;

import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.alipay.api.response.AlipayTradeCreateResponse;
import com.gzhryc.common.StringTools;
import com.gzhryc.common.json.JsonTools;
import com.gzhryc.common.logging.Logger;
import com.gzhryc.pay.adaptation.alipay.AlipayNormalPayService;
import com.gzhryc.pay.adaptation.weixin.WXPayNormalPayService;
import com.gzhryc.pay.adaptation.weixin.msg.normal.WXPayNormalPayResponse;
import com.gzhryc.servlet.WebUtils;
import com.gzhryc.servlet.annotation.Route;
import com.gzhryc.shared_device.base.enums.EOperatorType;
import com.gzhryc.shared_device.base.enums.EPayState;
import com.gzhryc.shared_device.base.enums.EPayType;
import com.gzhryc.shared_device.base.models.OperateInfo;
import com.gzhryc.shared_device.bxscn.code.BXSCNCostConfig;
import com.gzhryc.shared_device.bxscn.code.dao.db.BXSCNFeeTemplate;
import com.gzhryc.shared_device.bxscn.code.dao.db.BXSCNOrder;
import com.gzhryc.shared_device.bxscn.code.dao.db.PortableEnergyCabinet;
import com.gzhryc.shared_device.bxscn.code.dao.db.PortableEnergyCabinetSlot;
import com.gzhryc.shared_device.bxscn.code.dao.enums.BXSCNOrderEnum;
import com.gzhryc.shared_device.bxscn.code.services.BXSCNFeeTemplateService;
import com.gzhryc.shared_device.bxscn.code.services.BXSCNOrderService;
import com.gzhryc.shared_device.common.device.dao.db.Device;
import com.gzhryc.shared_device.common.device.services.DeviceService;
import com.gzhryc.shared_device.common.payment.dao.db.AlipayOrder;
import com.gzhryc.shared_device.common.payment.dao.db.WXPayOrder;
import com.gzhryc.shared_device.common.payment.services.AlipayOrderService;
import com.gzhryc.shared_device.common.payment.services.WXPayOrderService;
import com.gzhryc.shared_device.oem.code.ConfigUtils;
import com.gzhryc.shared_device.oem.code.PayServiceFactory;
import com.gzhryc.shared_device.oem.code.business.EBusinessType;
import com.gzhryc.shared_device.oem.code.config.dao.enums.EAgreementCode;
import com.gzhryc.shared_device.oem.code.device.BXSCNCacheManager;
import com.gzhryc.shared_device.oem.code.device.EDeviceFunCode;
import com.gzhryc.shared_device.oem.code.member.LoginMember;
import com.gzhryc.shared_device.oem.code.member.services.MemberAgreementService;
import com.gzhryc.shared_device.oem.code.order.CacheOrderCollect;
import com.gzhryc.shared_device.oem.code.place.dao.db.PlaceBusinessConfig;
import com.gzhryc.shared_device.oem.code.place.services.PlaceBusinessConfigService;
import com.gzhryc.shared_device.oem.micro.api.MicroConstants;
import com.gzhryc.shared_device.oem.micro.api.OrderCollectManager;
import com.gzhryc.shared_device.oem.micro.api.dto.xcx.ClientAPICodeConstants;
import com.gzhryc.shared_device.oem.micro.api.dto.xcx.PayResultCode;
import com.gzhryc.shared_device.oem.micro.api.dto.xcx.v1.bxscn.BXSCNLeasePayRequest;
import com.gzhryc.shared_device.oem.micro.api.dto.xcx.v1.bxscn.BXSCNLeasePayResponse;
import com.gzhryc.shared_device.oem.micro.api.dto.xcx.v1.bxscn.BXSCNPayResultRequest;
import com.gzhryc.shared_device.oem.micro.api.dto.xcx.v1.bxscn.BXSCNPayResultResponse;

public class BXSCNPayController {

    static Logger log = Logger.getLogger(BXSCNPayController.class);

    @Route(value = {"/xcx/v1/bxscn/lease/pay.do"}, method = "POST")
    public BXSCNLeasePayResponse leasePay(HttpServletRequest request, HttpServletResponse response) {
        BXSCNLeasePayResponse apiResp = new BXSCNLeasePayResponse(ClientAPICodeConstants.EXECUTE_ERROR, "支付失败，请稍后再试");
        try {
            BXSCNLeasePayRequest apiReq = WebUtils.getJsonRequest(request, BXSCNLeasePayRequest.class);
            if (apiReq != null && StringTools.isNotBlank(apiReq.getBody().getDeviceSn())) {
                String deviceSn = apiReq.getBody().getDeviceSn().trim();
                Integer payType = apiReq.getBody().getPayType() == null ? EPayType.WXPay.index() : apiReq.getBody().getPayType();

                if (EPayType.WXPay.index().equals(payType) || EPayType.Alipay.index().equals(payType)) {
                    if (StringTools.isBlank(apiReq.getBody().getAppId())) {
                        apiResp.setMsg("无效的应用ID");
                        return apiResp;
                    }
                }
                
                LoginMember loginMember = WebUtils.getAttribute(request, MicroConstants.ATTR_LOGIN_MEMBER, LoginMember.class);

                Device device = DeviceService.self().getByDeviceSn(deviceSn);
                if (device == null || device.getPlaceId() == null) {
                    apiResp.setMsg("设备未部署");
                    return apiResp;
                }

                PortableEnergyCabinet portableEnergyCabinet = BXSCNCacheManager.self().getPortableEnergyCabinet(deviceSn);
                if (portableEnergyCabinet == null) {
                    apiResp.setMsg("设备离线");
                    return apiResp;
                }

                List<PortableEnergyCabinetSlot> energyCabinetSlotList = BXSCNCacheManager.self().findPortableEnergyCabinetSlot(deviceSn);
                if(energyCabinetSlotList != null && energyCabinetSlotList.size() > 0){
                    boolean flag = true;
                    for(PortableEnergyCabinetSlot energyCabinetSlot : energyCabinetSlotList){
                        if(StringTools.isNotBlank(energyCabinetSlot.getPortableBatterySn())){
                            flag = false;
                            break;
                        }
                    }
                    if(flag){
                        apiResp.setMsg("设备无可租借的电池");
                        return apiResp;
                    }
                }else{
                    apiResp.setMsg("设备无可租借的电池");
                    return apiResp;
                }

                //同意协议
                if (StringTools.isNotBlank(apiReq.getBody().getAppId())) {
                	MemberAgreementService.self().signing(loginMember.getId(), EAgreementCode.RentAgreement.name(), apiReq.getBody().getAppId());
                }

                BXSCNFeeTemplate feeTemplate = null;
                PlaceBusinessConfig deviceFunc = PlaceBusinessConfigService.self().getByKeys(device.getPlaceId(), EDeviceFunCode.BXSCN.index());
                if (deviceFunc != null && deviceFunc.getFeeTemplateId() != null) {
                    feeTemplate = BXSCNFeeTemplateService.self().getById(deviceFunc.getFeeTemplateId());
                }

                if (feeTemplate == null) {
                    BXSCNCostConfig costConfig = ConfigUtils.getBXSCNCostConfig();
                    feeTemplate = BXSCNFeeTemplateService.buildByDefault(costConfig);
                }
                
                OperateInfo operateInfo = new OperateInfo(MicroConstants.PROGRAM_TYPE, MicroConstants.PROGRAM_TYPE_NAME);
                operateInfo.setOperator(EOperatorType.Member.index(), loginMember.getFullName());
                operateInfo.setOperateNote("租借便携式储能电池");

                if (EPayType.WXPay.index().equals(payType)) {
                    WXPayNormalPayService payService = PayServiceFactory.self().getWXPayNormalPayService(apiReq.getBody().getAppId(),
                            EBusinessType.BXSCN.index());
                    if (payService == null) {
                        apiResp.setMsg("未配置应用支付服务");
                        return apiResp;
                    }

                    CacheOrderCollect orderCollect = OrderCollectManager.buildBXSCNCacheOrderCollect(loginMember, device, portableEnergyCabinet,
                            feeTemplate, payService.getConfig(), operateInfo);
                    if (orderCollect == null) {
                        apiResp.setMsg("创建订单失败，请稍后再试");
                        return apiResp;
                    }

                    WXPayNormalPayResponse externalResult = payService.applyPayOrder(orderCollect.getPayOrder());
                    if (externalResult != null) {
                        if(StringTools.isNotBlank(externalResult.getPrepay_id())) {
                            String payInfo = payService.buildXCXData(externalResult.getPrepay_id());
                            if (StringTools.isNotBlank(payInfo)) {
                                OrderCollectManager.saveWXPayOrderExternalContent(orderCollect.getPayOrder().getTradeNo(), JsonTools.toJson(externalResult));
                                log.info("微信支付返回：" + payInfo);
                                apiResp.setCode(ClientAPICodeConstants.SUCCESS, null);
                                apiResp.getBody().setTradeNo(orderCollect.getPayOrder().getTradeNo());
                                apiResp.getBody().setPayType(payType);
                                apiResp.getBody().setPayInfo(payInfo);
                            }
                        }else {
                            log.error("微信支付返回错误，返回信息：{{0:json}}", externalResult);
                        }
                    } else {
                        log.error("微信支付无返回，订单信息：{{0:json}}", orderCollect);
                    }
                }else if(EPayType.Alipay.index().equals(payType)) {
                	AlipayNormalPayService payService = PayServiceFactory.self().getAlipayNormalPayService(apiReq.getBody().getAppId(),
                            EBusinessType.BXSCN.index());
                    if (payService == null) {
                        apiResp.setMsg("未配置应用支付宝支付服务");
                        return apiResp;
                    }
                    
                    CacheOrderCollect orderCollect = OrderCollectManager.buildBXSCNCacheOrderCollect(loginMember, device, portableEnergyCabinet,
                            feeTemplate, payService.getConfig(), operateInfo);
                    if (orderCollect == null) {
                        apiResp.setMsg("创建订单失败，请稍后再试");
                        return apiResp;
                    }
                    
                    AlipayTradeCreateResponse externalResult = payService.applyPayOrder(orderCollect.getAlipayOrder());
                    if (externalResult != null) {
                        if(StringTools.isNotBlank(externalResult.getOutTradeNo())) {
                        	OrderCollectManager.saveAlipayOrderExternalContent(orderCollect.getAlipayOrder().getTradeNo(), JsonTools.toJson(externalResult));
                            apiResp.setCode(ClientAPICodeConstants.SUCCESS, null);
                            apiResp.getBody().setTradeNo(externalResult.getTradeNo());
                            apiResp.getBody().setPayType(payType);
                        }else {
                            log.error("支付宝支付返回错误，返回信息：{{0:json}}", externalResult);
                        }
                    } else {
                        log.error("支付宝支付无返回，订单信息：{{0:json}}", orderCollect);
                    }
                }else {
                	 apiResp.setMsg("无效的支付类型");
                     return apiResp;
                }
            }
        } catch (Exception e) {
            log.error("创建订单失败，" + e.getMessage(), e);
        }
        return apiResp;
    }

    @Route(value = {"/xcx/v1/bxscn/pay/result.do"}, method = "POST")
    public BXSCNPayResultResponse payResult(HttpServletRequest request) {
        BXSCNPayResultResponse apiResp = new BXSCNPayResultResponse(ClientAPICodeConstants.NULL_DATA, "未找到支付结果");
        try {
            BXSCNPayResultRequest apiReq = WebUtils.getJsonRequest(request, BXSCNPayResultRequest.class);
            if (apiReq != null && apiReq.getBody().getPayType() != null && StringTools.isNotBlank(apiReq.getBody().getTradeNo())) {
                Date createDate = new Date();
                String tradeNo = apiReq.getBody().getTradeNo().trim();      //去空格

                if (EPayType.WXPay.index().equals(apiReq.getBody().getPayType())) {
                    WXPayOrder payOrder = WXPayOrderService.self(createDate).getByTradeNo(tradeNo);
                    if (payOrder != null) {
                        apiResp.setCode(ClientAPICodeConstants.SUCCESS, null);
                        apiResp.getBody().setResultCode(PayResultCode.WAIT);
                        if (EPayState.Success.index().equals(payOrder.getPayStatus())) {
                            BXSCNOrder deviceOrder = BXSCNOrderService.self(new Date()).getByTradeNo(payOrder.getBusinessTradeNo());
                            if (deviceOrder != null) {
                                if (BXSCNOrderEnum.State.Lease.index().equals(deviceOrder.getState())) {
                                    apiResp.getBody().setResultCode(PayResultCode.SUCCESS);
                                    apiResp.getBody().setSlotNum(deviceOrder.getLeaseSlotNum());
                                    return apiResp;
                                } else if (BXSCNOrderEnum.State.LeaseFail.index().equals(deviceOrder.getState())) {
                                    apiResp.getBody().setResultCode(PayResultCode.FAIL);
                                    return apiResp;
                                }
                            } else {
                                log.error("未找到设备订单，支付订单号：{{0}}，业务订单号：{{1}}", payOrder.getTradeNo(), payOrder.getBusinessTradeNo());
                            }
                        }
                    }
                }else if(EPayType.Alipay.index().equals(apiReq.getBody().getPayType())){
                    AlipayOrder payOrder = AlipayOrderService.self(createDate).getByTradeNo(apiReq.getBody().getTradeNo());
                    if (payOrder != null) {
                        apiResp.setCode(ClientAPICodeConstants.SUCCESS, null);
                        apiResp.getBody().setResultCode(PayResultCode.WAIT);
                        if (EPayState.Success.index().equals(payOrder.getPayStatus())) {
                        	BXSCNOrder deviceOrder = BXSCNOrderService.self(new Date()).getByTradeNo(payOrder.getBusinessTradeNo());
                            if (deviceOrder != null) {
                                if (BXSCNOrderEnum.State.Lease.index().equals(deviceOrder.getState())) {
                                    apiResp.getBody().setResultCode(PayResultCode.SUCCESS);
                                    apiResp.getBody().setSlotNum(deviceOrder.getLeaseSlotNum());
                                    return apiResp;
                                } else if (BXSCNOrderEnum.State.LeaseFail.index().equals(deviceOrder.getState())) {
                                    apiResp.getBody().setResultCode(PayResultCode.FAIL);
                                    return apiResp;
                                }
                            } else {
                                log.error("未找到设备订单，支付订单号：{{0}}，业务订单号：{{1}}", payOrder.getTradeNo(), payOrder.getBusinessTradeNo());
                            }
                        }
                    }
                }else if(EPayType.EWallet.index().equals(apiReq.getBody().getPayType())){
                	BXSCNOrder deviceOrder = BXSCNOrderService.self(createDate).getByTradeNo(tradeNo);
                    if (deviceOrder != null) {
                        apiResp.setCode(ClientAPICodeConstants.SUCCESS, null);
                        apiResp.getBody().setResultCode(PayResultCode.WAIT);
                        if (BXSCNOrderEnum.State.Lease.index().equals(deviceOrder.getState())) {
                            apiResp.getBody().setResultCode(PayResultCode.SUCCESS);
                            apiResp.getBody().setSlotNum(deviceOrder.getLeaseSlotNum());
                        } else if (BXSCNOrderEnum.State.LeaseFail.index().equals(deviceOrder.getState())) {
                            apiResp.getBody().setResultCode(PayResultCode.FAIL);
                        }
                    } else {
                        log.error("未找到设备订单，支付类型：{{0}}，业务订单号：{{1}}", EPayType.EWallet.note(), tradeNo);
                    }
                }else {
	               	 apiResp.setMsg("无效的支付类型");
	                 return apiResp;
	            }
            }
        } catch (Exception e) {
            log.error("获取订单结果失败，" + e.getMessage(), e);
        }
        return apiResp;
    }
}
